﻿using UnityEngine;

namespace CWM.Skinn
{
    /// <summary>
    /// This component is for the editor only.
    /// You can save this asset as a prefab just make sure to save the meshes when prompted.
    /// </summary>
    [DisallowMultipleComponent]
    [AddComponentMenu("")]
    public class TexturePacker : MonoBehaviour
    {
        [ComponentHeader]
        public string header = "";

        [HighlightNull(true)]
        [Tooltip("the renderer to create a atlas for")]
        public Renderer source = null;

        [Disabled]
        public int vertexCount = 0;

        [Space]

        [Header("Render Settings")]

        public RenderQuality atlasSize = RenderQuality.x512;

        [Tooltip("bake color, emission, uv offset, and uv scale into atlas texture.")]
        public bool bakeMaterialProperties = false;

        [Tooltip("pad textures?")]
        public bool padding = true;

        [Range(0.1f, 5f)]
        [Tooltip("size of the padding.")]
        public float paddingSize = 1;

        [Range(2, 100)]
        [Tooltip("padding iterations.")]
        public int paddingIterations = 3;

        [Header("Exclude Textures")]

        [Tooltip("exclude textures from padding using property name.")]
        public string[] exculdeFromPadding = new string[]  { "DetailA", "DetailM" };

        [Tooltip("exclude textures from rendering using property name.")]
        public string[] exculdeFromRenderer = new string[] { "MatCap" };

        [Header("Defaults")]

        [Disabled]
        [Tooltip("a default normal map is used when textures are missing. always true in this version.")]
        public bool normalBump = true;

        [Tooltip("default _MetallicGlossMap when textures are missing.")]
        [Range(0f, 1f)]
        public float metallic = 0f;

        [Tooltip("default _SpecGlossMap when textures are missing.")]
        [Range(0f, 1f)]
        public float glossiness = 0.5f;

        [Header("Advanced")]
        public bool showHelp = true;

        [ClampAbs]
        [Tooltip("if greater than zero this value will be used during the layout. set a custom value if the automatic value fails.")]
        public int customGridSize = 0;

        [Tooltip("used to match uv islands.")]
        public string uvIslandID = "_MainTex";

        [Disabled]
        public Renderer tempRenderer = null;
        
        [System.Serializable]
        public class RendererData
        {
            public Renderer renderer = null; [HideInInspector] public int[] indices = new int[0];
        }

        [HideInInspector] public RendererData[] submeshes = new RendererData[0];

        public static readonly Vector3 Center = new Vector3(50f, 0, 50f);
        public static readonly Vector3 Size = new Vector3(100f, 0, 100f);


#if UNITY_EDITOR
        private void Reset()
        {
            foreach (var transform in transform.GetAllChildren()) if(transform) SkinnEx.Release(transform.gameObject);
        }
        
        private void OnDrawGizmos()
        {
            var gizmosColor = Gizmos.color;
            Gizmos.color = Color.green;

            Gizmos.DrawWireCube(Center, Size);

            if (transform.parent) this.transform.SetParent(null);
            transform.localPosition = Vector3.zero;
            transform.localRotation = Quaternion.identity;
            transform.localScale = Vector3.one;

            Gizmos.color = Color.green * 0.5f;

            foreach (var data in submeshes)
            {
                var renderer = data.renderer;
                if (!renderer) continue;
                var rTransform = renderer.transform;
                if (rTransform.root != transform) rTransform.SetParent(transform);
                if (rTransform.parent != transform)
                {
                    rTransform.localPosition = Vector3.zero;
                    rTransform.localRotation = Quaternion.identity;
                    rTransform.localScale = Vector3.one;
                    continue;
                }

                var position = rTransform.position;
                position.y = 0f;
                rTransform.localPosition = position;

                var scale = rTransform.localScale;
                scale.x = Mathf.Abs(scale.x);
                scale.y = 1f;
                scale.z = Mathf.Abs(scale.z);
                rTransform.localScale = scale;

                var rotation = rTransform.localRotation.eulerAngles;
                rotation.x = 0f;
                rotation.z = 0f;
                rTransform.localRotation = Quaternion.Euler(rotation);

                if (rotation.y != 0f) continue;

                var center = rTransform.position + ((rTransform.localScale - Vector3.up) * 0.5f) * 100f;
                var size = (rTransform.localScale - Vector3.up) * 100f;
                Gizmos.DrawWireCube(center, size);
            }

            Gizmos.color = gizmosColor;
        }
#endif

    }
}

